#include <iostream>
#include <iterator>
#include <cstring>
#include <typeinfo>
#include <algorithm>
#include <array>
#include <vector>
//#include <string_view>
//#define __STDC_WANT_LIB_EXT1__ 1

//enum class StudentNames
//{
//    kenny, // 0
//    kyle, // 1
//    stan, // 2
//    butters, // 3
//    cartman, // 4
//    wendy, // 5
//    max_students // 6
//};

using namespace std;

namespace StudentNames
{
    enum StudentNames
    {
        kenny, // 0
        kyle, // 1
        stan, // 2
        butters, // 3
        cartman, // 4
        wendy, // 5
        max_students // 6
    };
}

bool isVowel(char ch)
{
  switch (ch)
  {
  case 'A':
  case 'a':
  case 'E':
  case 'e':
  case 'I':
  case 'i':
  case 'O':
  case 'o':
  case 'U':
  case 'u':
    return true;
  default:
    return false;
  }
}

void changeN(const int& ref)
{
//    ref = 6;
    std::cout << ref;
}

int main()
{
    int array[]{ 1, 1, 2, 3, 5, 8, 13, 21 };
    std::cout << "The array has: " << sizeof(array) / sizeof(int) << " elements\n";

    int prime[StudentNames::max_students]{ 2 };
    for(int count = 0; count < 2; ++count)
    {
        std::cout << prime[count] << '\t';
    }

    char myString[]{ "string" };
    for (int index{ 0 }; index < 7; ++index)
        std::cout << static_cast<int>(myString[index]) << ' ';

    std::cout << "=============\n";
    char source[]{ "Copy this!" };
    char dest[5];
    strcpy(dest, source);   // 并非所有编译器都支持strcpy_s（）
    std::cout << dest << '\n';

    int x{ 4 };
    std::cout << typeid(&x).name() << '\n'; // 指针名字

    // 9.11		指针算术和数组索引
    char name[]{ "Mollie" };
    auto numVowels{ std::count_if(std::begin(name), std::end(name), isVowel) };

    std::cout << name << " has " << numVowels << " vowels.\n";

    // 9.13		使用new和delete动态分配内存
    // 在许多情况下，不希望使用new引发异常（或使程序崩溃），因此，可以使用new的另一种形式来代替new告诉new如果无法分配内存，则返回空指针。
    // 这是通过在new关键字和分配类型之间添加常量std :: nothrow来完成的：
    int* value = new(std::nothrow) int;
    if(!value)
    {
        std::cout << "Could not allocate memory\n";
    }
    else{
        *value = 7;
        std::cout << "*value = " << *value << '\n';
        delete value;
        value = nullptr;
    }

    // 9.14		动态分配数组
    int fixedArray[5] = { 1, 2, 45, 2, 3 };
    int* array2{ new int[5]{ 1, 2, 45, 2, 3 } };
    auto* array3{ new int[5]{ 1, 2, 45, 2, 3 } };
    (void)fixedArray;
    (void)array2;
    (void)array3;

//    char *array4 = new char[14] { "Hello, world!" }; // doesn't work in GCC, though it should

    // 9.16		参考变量
    int n{ 5 };
    std::cout << n << '\n';

    changeN(n);

    std::cout << n << '\n';

    // 9.19		每个循环
    constexpr int fibonacci[]{ 0, 1, 1, 2, 3 };
    for(int number : fibonacci)
    {
        std::cout << number << ' ';
    }

    std::cout << '\n';

    std::string strs[]{ "peter", "likes", "yogurt" };
    for(auto& element: strs)
    {
        std::cout << element << ' ';
    }

    std::cout << '\n';

    // 9.22 — std :: array简介
    std::array<int, 3> myArray = { 1, 2, 3 };
    myArray.at(0) = 9;  //返回对数组元素0的引用

    for(auto i : myArray)
    {
        std::cout << i << ' ';
    }
    std::cout << '\n';

    // 9.23 — std :: vector简介
    std::vector<int> array4 { 1, 2, 3 };
//    由于类型的变量会std::vector处理自己的内存管理（这有助于防止内存泄漏），
//    记住它们的长度并且可以轻松调整大小，因此我们建议std::vector在大多数需要动态数组的情况下使用。

    // 9.25 —标准库算法简介
    // auto found{ std::find(arr.begin(), arr.end(), search) };
    // auto found{ std::find_if(arr.begin(), arr.end(), containsNut) };
    // auto nuts{ std::count_if(arr.begin(), arr.end(), containsNut) };
    // std::sort(arr.begin(), arr.end(), greater);
    // std::sort(arr.begin(), arr.end(), std::greater<int>{}); // use the standard library greater comparison
    // std::for_each(arr.begin(), arr.end(), doubleNumber);

    return 0;
}
